import subprocess
import sys
import os
import threading
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk, ImageSequence
import random
import time
import keyboard
import psutil
import shutil
import json
from tkinterdnd2 import DND_FILES, TkinterDnD
import webbrowser
import requests
import winreg
import ctypes
import sys

def resource_path(relative_path):
    """ 获取资源的绝对路径"""
    if hasattr(sys, '_MEIPASS'):
        return os.path.join(sys._MEIPASS, relative_path)
    return os.path.join(os.path.abspath("."), relative_path)


class BubbleWindow(tk.Toplevel):
    def __init__(self, master, text):
        super().__init__(master)
        self.overrideredirect(True)
        self.wm_attributes("-topmost", True)
        self.wm_attributes("-transparentcolor", "white")

        # 气泡样式配置
        self.bg_color = "#FFFFCC"
        self.text_color = "#333333"
        self.font = ("微软雅黑", 10)
        self.corner_radius = 15  # 圆角半径
        self.line_spacing = 4  # 行间距
        self.max_line_width = 200  # 最大行宽（像素）

        # 创建画布绘制气泡
        self.canvas = tk.Canvas(self, bg="white", highlightthickness=0)
        self.canvas.pack()

        # 绘制气泡形状
        self._draw_bubble(text)

        # 自动关闭定时器
        self.after(3000, self.destroy)

    def _draw_rounded_rect(self, x1, y1, x2, y2, r, **kwargs):
        """绘制圆角矩形"""
        points = [
            x1 + r, y1,
            x2 - r, y1,
            x2, y1, x2, y1 + r,
            x2, y2 - r, x2 - r, y2,
            x1 + r, y2,
            x1, y2 - r,
            x1, y1 + r,
            x1 + r, y1
        ]
        return self.canvas.create_polygon(points, smooth=True, **kwargs)

    def _draw_bubble(self, text):
        """绘制气泡和文字"""
        # 计算文字尺寸
        temp_label = tk.Label(self, text=text, font=self.font)
        width = temp_label.winfo_reqwidth() + 30  # 增加边距
        height = temp_label.winfo_reqheight() + 20
        temp_label.destroy()

        # 计算气泡尺寸
        bubble_width = width + self.corner_radius * 2
        bubble_height = height + self.corner_radius * 2

        # 创建气泡主体
        self.canvas.config(width=bubble_width, height=bubble_height + 20)
        self._draw_rounded_rect(
            self.corner_radius, 0,
            bubble_width - self.corner_radius, bubble_height,
            self.corner_radius,
            fill=self.bg_color,
            outline=self.bg_color
        )

        # 底部箭头
        self.canvas.create_polygon(
            bubble_width // 2 - 10, bubble_height,
            bubble_width // 2, bubble_height + 15,
            bubble_width // 2 + 10, bubble_height,
            fill=self.bg_color,
            outline=self.bg_color
        )

        # 文字
        self.canvas.create_text(
            bubble_width // 2, bubble_height // 2,
            text=text,
            font=self.font,
            fill=self.text_color
        )


def auto_start():
    exe_path = sys.executable
    # 设置开机启动文件夹路径
    startup_folder = os.path.expandvars(r'%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup')
    # 复制文件到启动文件夹，如果它还不在那里
    exe_name = "oo宠物.exe"  # 可以是任何名字，但确保它唯一且具描述性
    destination = os.path.join(startup_folder, exe_name)
    # 如果文件还不存在，则复制
    if not os.path.isfile(destination):
        shutil.copy(exe_path, destination)


class TransparentGifWindow:
    def __init__(self, master, gif_path):
        self.master = master
        self.gif_path = gif_path
        self.status_update_callbacks = []

        self.bubble_texts = [
            "今天天气真好呀～",
            "要喂我吃点东西吗？",
            "来和我玩吧！",
            "双击可以关闭我哦",
            "拖着我到处逛逛吧",
            "💡杰哥为什么\n能力挽狂澜？？？",
            "你累不累呀？要不休息一下吧!",
            "人生没有那么多如果",
            "有什么比编程更容易呢？"
        ]

        # 窗口基础设置
        self.master.overrideredirect(True)
        self.master.wm_attributes("-topmost", True)
        self.master.wm_attributes("-transparentcolor", "white")
        self.master.geometry("70x70+500+300")

        self.pet_frames = []
        self.celebrate_frames = []
        self.load_gif_frames(resource_path("pet.gif"), self.pet_frames)
        self.load_gif_frames(resource_path("to22.gif"), self.celebrate_frames)
        self.current_frames = self.pet_frames
        self.current_frame = 0
        # 新增睡眠相关属性
        self.sleep_frames = []
        self.load_gif_frames(resource_path("sleep.gif"), self.sleep_frames)
        self.is_sleeping = False
        self.sleep_clicks = 0
        self.last_activity_time = time.time()  # 最后活动时间

        self.cry_frames = []
        self.load_gif_frames(resource_path("cry.gif"), self.cry_frames)
        self.is_crying = False
        self.cry_threshold = 30  # 哭泣阈值30%
        self.hide_frames = []
        self.load_hide_image(resource_path("hide.png"))  # 加载躲藏图片

        self.is_hiding = False
        self.hide_check_timer = None
        self.mouse_movement = 0
        self.hide_spot = None  # 存储躲藏位置信息
        self.hide_start_time = 0

        # 在初始化末尾添加不活动检查
        self.master.after(30000, self.check_activity)  # 每30秒检查一次

        # 创建显示容器
        self.label = tk.Label(self.master, bg="white")
        self.label.pack()

        self.label.drop_target_register(DND_FILES)
        self.label.dnd_bind('<<Drop>>', self.on_file_drop)
        self.label.bind("<ButtonRelease-1>", self.on_click_pet)

        # 事件绑定
        self.label.bind("<ButtonPress-1>", self.start_drag)
        self.label.bind("<B1-Motion>", self.on_drag)
        self.label.bind("<Double-Button-1>", self.close_window)
        self.label.bind("<Button-3>", self.show_context_menu)
        # 新增状态系统
        self.status_file = os.path.expanduser("~/pet_status.json")
        self.load_status()  # 加载保存的状态
        self.last_reminder_time = 0  # 添加这个属性

        # 添加新的实例属性
        self.click_messages = [
            "别点我~ 好痒痒~",
            "再点我要生气了！😠",
            "摸这里会掉毛的！",
            "检测到持续点击...🐾",
            "这是鼻子不是按钮！👃",
            "信不信我咬你手指！🦷",
            "点击能量转化中...10%",
            "再点我就变成狗狗！🐶",
            "点击次数+1，积分+0"
        ]
        # 添加智能回复相关状态
        self.smart_reply_enabled = False
        self.last_request_time = 0
        self.request_cooldown = 5  # 请求冷却时间(秒)
        self.last_api_call_time = 0  # 新增API调用时间记录
        self.api_cooldown = 30  # 冷却时间30秒
        self.original_bubble_texts = self.bubble_texts.copy()
        self.original_click_messages = self.click_messages.copy()
        self.smart_reply_text = "💬 智能回复"

        # 右键菜单
        self.context_menu = tk.Menu(self.master, tearoff=0)
        self.context_menu.add_command(label="🍚 喂食", command=self.feed)
        self.context_menu.add_command(label="💧 喝水", command=self.drink_water)
        self.context_menu.add_command(label="🫳 摸一摸", command=self.pet_action)
        self.context_menu.add_command(label="🎨 更换皮肤", command=self.change_skin)
        self.context_menu.add_command(label="🆑 吃系统垃圾", command=self.eating_garbage)
        self.context_menu.add_command(label="🖰 鼠标跟随", command=self.mouse_follow)
        self.context_menu.add_command(label="🕵 捉迷藏", command=self.start_hide)
        # self.context_menu.add_command(label="💬 智能回复", command=self.smart_reply)
        self.context_menu.add_command(
            label=self.smart_reply_text,
            command=self.toggle_smart_reply
        )
        self.context_menu.add_command(label="⚙ 设置", command=self.change_timing)
        self.context_menu.add_command(label="▶ 开机自启动", command=auto_start)
        self.context_menu.add_separator()

        self.context_menu.add_command(label="📴 退出", command=self.close_window)

        # 启动状态消耗定时器
        self.status_timer = self.master.after(60000, self.consume_status)  # 每分钟消耗一次

        # 气泡显示定时器
        self.bubble_timer = None
        self.start_bubble_timer()

        # 初始化监听功能
        self.setup_listeners()

        # 动画循环
        self.animate()

    def load_hide_image(self, img_path):
        """加载躲藏静态图片"""
        try:
            img = Image.open(img_path).resize((70, 70), Image.Resampling.LANCZOS)
            photo = ImageTk.PhotoImage(img.convert("RGBA"))
            self.hide_frames = [photo]  # 创建单帧列表
        except Exception as e:
            print(f"加载躲藏图片失败: {str(e)}")
            self.hide_frames = self.pet_frames  # 失败时使用默认帧

    def add_status_update_callback(self, callback):
        """添加状态更新回调"""
        self.status_update_callbacks.append(callback)

    def notify_status_update(self):
        """通知所有回调函数状态已更新"""
        for callback in self.status_update_callbacks:
            callback(self.status)

    def setup_listeners(self):
        """初始化事件监听器"""
        # 键盘快捷键监听
        keyboard.add_hotkey('ctrl+c', self.show_cv_message)

        # 软件进程监听配置
        self.monitored_softwares = {
            '准备用 VS Code？主人💡': 'Code.exe',
            '记事本': 'Notepad.exe',
            'Chrome': 'chrome.exe'
        }
        self.running_processes = set()
        self.start_process_monitor()
        self.master.bind('<Motion>', self.mouse_movement_handler)

    def show_cv_message(self):
        """显示CV提示"""
        self.master.after(0, self.show_random_bubble, "😂又要CV大法了？")

    def start_process_monitor(self):
        """启动进程监控"""
        self.master.after(1000, self.check_processes)

    def check_processes(self):
        """检查正在运行的进程"""
        current_processes = set()
        for proc in psutil.process_iter(['name']):
            if proc.info['name'] in self.monitored_softwares.values():
                current_processes.add(proc.info['name'])

        # 检测新启动的软件
        new_processes = current_processes - self.running_processes
        for proc_name in new_processes:
            software_name = [k for k, v in self.monitored_softwares.items() if v == proc_name][0]
            print(software_name)
            self.master.after(0, self.show_random_bubble, f"{software_name}！")

        self.running_processes = current_processes
        self.master.after(5000, self.check_processes)

    def load_gif_frames(self, gif_path, target_list):
        """加载GIF到指定列表"""
        gif = Image.open(gif_path)
        target_list.clear()
        for frame in ImageSequence.Iterator(gif):
            resized_frame = frame.resize((70, 70), Image.Resampling.LANCZOS)
            photo = ImageTk.PhotoImage(resized_frame.convert("RGBA"))
            target_list.append(photo)

    def animate(self):
        """更新动画帧"""
        if self.current_frames:
            self.label.config(image=self.current_frames[self.current_frame])
            self.current_frame = (self.current_frame + 1) % len(self.current_frames)
        self.master.after(100, self.animate)

    def start_celebration(self):
        """开启庆祝状态"""
        self.current_frames = self.celebrate_frames
        self.current_frame = 0
        self.show_random_bubble("🎉 太开心了！心情满格！")
        self.master.after(2000, self.end_celebration)

    def end_celebration(self):
        """结束庆祝状态"""
        self.current_frames = self.pet_frames
        self.current_frame = 0

    def show_context_menu(self, event):
        """显示右键菜单"""
        try:
            self.context_menu.tk_popup(event.x_root, event.y_root)
        finally:
            self.context_menu.grab_release()

    def toggle_smart_reply(self):
        """切换智能回复状态并更新菜单标签"""
        self.smart_reply_enabled = not self.smart_reply_enabled

        # 更新文本变量
        new_text = "🛑 停止智能回复" if self.smart_reply_enabled else "💬 智能回复"
        self.smart_reply_text = new_text

        # 手动更新菜单项的标签
        self.context_menu.entryconfigure(7, label=new_text)

        # 其他状态更新逻辑
        if self.smart_reply_enabled:
            self.show_random_bubble("智能回复模式已开启！")
            self.bubble_texts = ["正在连接大脑..."]
            self.click_messages = ["思考中..."]
        else:
            self.show_random_bubble("智能回复模式已关闭")
            self.bubble_texts = self.original_bubble_texts.copy()
            self.click_messages = self.original_click_messages.copy()

    def _eat_shortcut(self, lnk_path):
        try:
            """处理快捷方式"""
            # 获取快捷方式实际指向路径
            from win32com.client import Dispatch
            shell = Dispatch('WScript.Shell')
            shortcut = shell.CreateShortCut(lnk_path)
            real_path = shortcut.TargetPath

            # 根据文件类型提供不同增益
            if real_path.lower().endswith(('.exe', '.bat')):
                self.feed(bonus=30, message="吃到程序文件！能量++")
                self.notify_status_update()
            elif real_path.lower().endswith(('.txt', '.doc')):
                self.feed(bonus=15, message="吃到文档文件～知识就是力量")
                self.notify_status_update()
            else:
                self.feed(bonus=10, message="吃到未知文件")
                self.notify_status_update()
            # 仅保留提示，不删除文件
            self.show_random_bubble("吃饱啦！快捷方式还在哦~")
        except Exception as e:
            self.show_random_bubble(f"消化不良：{str(e)}")
            self.status["mood"] = max(0, self.status["mood"] - 10)
            self.notify_status_update()

    def on_file_drop(self, event):
        try:
            # 增强路径兼容性处理
            file_path = event.data.strip('{}').replace('\\', '/').replace('//', '/')

            # 调试输出（打包后需移除）
            print(f"[DEBUG] 收到拖放文件: {file_path}")

            if not os.path.exists(file_path):
                self.show_random_bubble("文件不存在！")
                return

            if file_path.lower().endswith('.lnk'):
                self._eat_shortcut(file_path)
            else:
                self.show_random_bubble("我只吃快捷方式哦~")
        except Exception as e:
            self.show_random_bubble(f"吃坏肚子了: {str(e)}")

    def feed(self, bonus=30, message=None):
        """增强版喂食功能"""
        if self.is_sleeping:
            self.show_random_bubble("😴 睡觉中不接受投喂")
            return

        self.last_activity_time = time.time()  # 更新活动时间
        if self.status["hunger"] >= 100:
            self.show_random_bubble("已经吃饱啦～")
            return

        # 动态计算增量
        actual_add = min(bonus, 100 - self.status["hunger"])
        self.status["hunger"] += actual_add
        self.status["mood"] = min(100, self.status["mood"] + 10 + actual_add // 5)

        # 显示自定义消息
        if message:
            display_msg = f"{message} (+{actual_add}%饱腹)"
        else:
            display_msg = random.choice([
                f"饥饿值+{actual_add}% ({self.status['hunger']}%)",
                "谢谢主人投喂～😋",
                "味道不错！🍖"
            ])

        self.show_random_bubble(display_msg)
        self.last_reminder_time = 0
        if self.status["hunger"] >= 20 and self.status["thirst"] >= 20:
            self.exit_cry_state()

    def change_skin(self):
        """更换皮肤"""
        self.show_random_bubble("🙈还没衣服...")

    def change_timing(self):
        """定时功能"""
        self.show_random_bubble("定时...")
        timing_window = TimingWindow(self.master)
        timing_window.main_app = self
        timing_window.master._transparent_window = self  # 建立引用
        self.add_status_update_callback(timing_window.on_status_update)

    def smart_reply(self):
        """智能回复功能"""
        try:
            config_path = os.path.expanduser("~/pet_gpt_config.json")
            if not os.path.exists(config_path):
                self.show_random_bubble("请先配置大模型设置！")
                return

            with open(config_path) as f:
                config = json.load(f)

            if not config.get('api_url') or not config.get('api_key'):
                self.show_random_bubble("请先配置API URL和Key！")
                return

            # 获取当前状态生成prompt
            # prompt = f"当前状态：心情{self.status['mood']}% 饱腹{self.status['hunger']}% 口渴{self.status['thirst']}%"
            prompt = "你好啊"
            self.show_random_bubble("智能回复中！")

            def callback(result):
                print(result)
                self.master.after(0, self.show_random_bubble, f"{str(result)}")

            # 异步发送请求
            threading.Thread(
                target=self.call_gpt_api,
                args=(config, prompt, callback)
            ).start()

        except Exception as e:
            self.show_random_bubble(f"请求失败：{str(e)}")

    resl = ""

    def call_gpt_api(self, config, prompt, callback):
        """调用GPT API"""
        try:
            headers = {
                "Authorization": f"Bearer {config['api_key']}",
                "Content-Type": "application/json"
            }

            request_data = config['training']
            request_data['messages'].append({
                "role": "user",
                "content": prompt
            })

            response = requests.post(
                config['api_url'],
                headers=headers,
                json=request_data,
                timeout=30
            )
            print(response)
            self.master.after(0, self.show_random_bubble, f"{response}！")
            if response.status_code == 200:
                result = response.json()
                reply = result['choices'][0]['message']['content']
                # print(reply)
                self.show_random_bubble(str(reply))
                self.master.after(0, self.show_random_bubble, reply, True)
            else:
                self.show_random_bubble(f"API错误：{response.text}")

        except Exception as e:
            self.master.after(0, self.show_random_bubble, f"请求异常：{str(e)}")

    def eating_garbage(self):
        """执行系统清理并增加饥饿值"""
        try:
            # 执行清理命令列表
            commands = [
                ('临时文件', r'del /s /q %temp%\*.*', 15),
                ('系统缓存', 'ipconfig /flushdns', 10),
                ('缩略图缓存', 'del /f /s /q %LocalAppData%\Microsoft\Windows\Explorer\thumbcache*', 20),
                ('预读取文件', 'del /f /s /q %SystemRoot%\prefetch\*.*', 25),
                ('DNS缓存', 'ipconfig /flushdns', 5),
                ('浏览器缓存', r'del /s /q "%LOCALAPPDATA%\Google\Chrome\User Data\Default\Cache\*.*"', 30)
            ]

            total_bonus = 0
            success_count = 0

            for name, cmd, bonus in commands:
                try:
                    # 执行命令（隐藏命令窗口）
                    process = subprocess.Popen(
                        cmd,
                        shell=True,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE,
                        creationflags=subprocess.CREATE_NO_WINDOW
                    )
                    _, stderr = process.communicate()

                    if process.returncode == 0:
                        total_bonus += bonus
                        success_count += 1
                    else:
                        raise Exception(f"{name}清理失败：{stderr.decode('gbk')}")
                except Exception as e:
                    print(f"清理错误: {str(e)}")

            # 根据清理效果计算最终增益
            if success_count > 0:
                # 基础增益 + 额外奖励（每成功2个项目加5点）
                actual_bonus = total_bonus + (success_count // 2) * 5
                actual_bonus = min(actual_bonus, 100 - self.status["hunger"])

                self.status["hunger"] += actual_bonus
                self.status["mood"] = min(100, self.status["mood"] + actual_bonus // 2)

                # 生成反馈消息
                performance = [
                    ("勉强吃了点渣渣", 0.3),
                    ("饱餐一顿", 0.6),
                    ("大快朵颐", 1.0)
                ]
                ratio = success_count / len(commands)
                msg = next((m for m, r in performance if ratio >= r), "吃得太撑了！")

                self.show_random_bubble(
                    f"🗑️ {msg}\n"
                    f"清理了{success_count}项垃圾\n"
                    f"饥饿值+{actual_bonus}% ({self.status['hunger']}%)"
                )

                # 添加动画效果
                if actual_bonus > 30:
                    self.start_celebration()
            else:
                self.show_random_bubble("没有找到可吃的垃圾...")
                self.status["mood"] = max(0, self.status["mood"] - 10)

        except Exception as e:
            self.show_random_bubble(f"吃坏肚子了: {str(e)}")
            self.status["mood"] = max(0, self.status["mood"] - 20)

        self.notify_status_update()

    # 新增状态管理方法
    def load_status(self):
        """加载保存的状态"""
        default_status = {
            "mood": 80,
            "hunger": 50,
            "thirst": 50,
            "last_saved": time.time()
        }

        try:
            if os.path.exists(self.status_file):
                with open(self.status_file, "r") as f:
                    saved_status = json.load(f)

                    # 计算离线时间消耗（每分钟1%）
                    offline_mins = (time.time() - saved_status["last_saved"]) // 60
                    for _ in range(int(offline_mins)):
                        saved_status["mood"] = max(0, saved_status["mood"] - 1)
                        saved_status["hunger"] = max(0, saved_status["hunger"] - 1)
                        saved_status["thirst"] = max(0, saved_status["thirst"] - 1)

                    self.status = {**default_status, **saved_status}
            else:
                self.status = default_status
        except:
            self.status = default_status

        # 限制数值范围
        self.status["mood"] = min(100, max(0, self.status["mood"]))
        self.status["hunger"] = min(100, max(0, self.status["hunger"]))
        self.status["thirst"] = min(100, max(0, self.status["thirst"]))

    def save_status(self):
        """保存当前状态"""
        self.status["last_saved"] = time.time()
        with open(self.status_file, "w") as f:
            json.dump(self.status, f)

    def consume_status(self):
        """每分钟消耗状态（已添加智能提醒）"""
        # 原有消耗逻辑保持不变...
        self.status["mood"] = max(0, self.status["mood"] - 1)
        self.status["hunger"] = max(0, self.status["hunger"] - 1)
        self.status["thirst"] = max(0, self.status["thirst"] - 2)

        # 检测是否需要哭泣（任意一项低于20%进入哭泣状态）
        should_cry = self.status["hunger"] < 20 or self.status["thirst"] < 20

        # 状态切换逻辑
        if should_cry and not self.is_crying:
            self.enter_cry_state()
        elif not should_cry and self.is_crying:
            self.exit_cry_state()

        # 智能提醒系统
        current_time = time.time()
        if self.status["hunger"] < 30 and (current_time - self.last_reminder_time) > 300:  # 5分钟提醒间隔
            remaining = int(300 - (current_time - self.last_reminder_time))
            hunger_level = "⚠️" if self.status["hunger"] > 20 else "❌"
            self.show_random_bubble(
                f"{hunger_level}该喂食啦！饥饿值：{self.status['hunger']}%\n"
                f"(还剩{remaining // 60}分{remaining % 60}秒后提醒)"
            )
            self.last_reminder_time = current_time

        # 原有低状态提醒...
        if self.status["thirst"] < 20:
            self.show_random_bubble("好渴啊...🥵")
        elif self.status["hunger"] < 20:  # 保留原有20%的紧急提醒
            self.show_random_bubble("好饿...🍔")
        elif self.status["mood"] < 20:
            self.show_random_bubble("心情不好...💢")

        # 重新启动定时器
        self.status_timer = self.master.after(60000, self.consume_status)

    def enter_cry_state(self):
        """进入哭泣状态"""
        if not hasattr(self, 'cry_frames'):
            self.cry_frames = []
            self.load_gif_frames(resource_path("cry.gif"), self.cry_frames)

        self.is_crying = True
        self.current_frames = self.cry_frames
        self.current_frame = 0
        self.show_random_bubble("😭 呜呜...好难受...")
        # 立即取消睡眠状态（如果正在睡）
        if self.is_sleeping:
            self.wake_up(manual=True)

    def exit_cry_state(self):
        """退出哭泣状态"""
        self.is_crying = False
        self.current_frames = self.pet_frames
        self.current_frame = 0
        self.show_random_bubble("😢 感觉好多了...")
        # 重置活动时间防止立即睡觉
        self.last_activity_time = time.time()

    def drink_water(self):
        """喝水操作"""
        if self.status["thirst"] >= 100:
            self.show_random_bubble("已经喝不下啦～")
            return

        self.status["thirst"] = min(100, self.status["thirst"] + 25)
        self.show_random_bubble(f"喝饱了～ ({self.status['thirst']}%)")
        self.status["mood"] = min(100, self.status["mood"] + 5)
        if self.status["hunger"] >= 20 and self.status["thirst"] >= 20:
            self.exit_cry_state()

    def pet_action(self):
        """摸一摸操作（已添加庆祝触发）"""
        original_mood = self.status["mood"]
        self.status["mood"] = min(100, self.status["mood"] + 15)

        # 检测是否达到100%心情
        if original_mood < 100 and self.status["mood"] >= 100:
            self.start_celebration()

        self.show_random_bubble(random.choice([
            "好开心～😊",
            "还要继续摸～",
            "心情+15！✨",
            f"心情：{self.status['mood']}%"
        ]))

    def start_bubble_timer(self):
        """启动随机气泡定时器"""
        self.show_random_bubble()
        self.bubble_timer = self.master.after(10000, self.start_bubble_timer)

    def show_random_bubble(self, custom_text=None, force=False):
        if self.is_hiding:
            return
        """显示随机气泡"""
        if self.smart_reply_enabled and not custom_text:
            # 从API获取随机消息
            if time.time() - self.last_request_time > self.request_cooldown:
                threading.Thread(target=self.fetch_ai_message).start()
            return

        if force:
            if hasattr(self, 'current_bubble'):
                try:
                    self.current_bubble.destroy()
                except:
                    pass
                del self.current_bubble

        if hasattr(self, 'current_bubble') and self.current_bubble.winfo_exists():
            return

        text = custom_text if custom_text else random.choice(self.bubble_texts)
        self.current_bubble = BubbleWindow(self.master, text)


        # 计算气泡位置（精确对齐宠物中心）
        main_x = self.master.winfo_x()
        main_y = self.master.winfo_y()
        main_width = self.master.winfo_width()
        main_height = self.master.winfo_height()

        # 获取气泡实际尺寸
        self.current_bubble.update_idletasks()  # 强制更新几何信息
        bubble_width = self.current_bubble.winfo_width()
        bubble_height = self.current_bubble.winfo_height()

        # 计算气泡位置（箭头对准宠物中心）
        bubble_x = main_x + main_width//2 - bubble_width//2  # 水平居中
        bubble_y = main_y - bubble_height  # 垂直位置在宠物头顶

        self.current_bubble.geometry(f"+{int(bubble_x)}+{int(bubble_y)}")

    def fetch_ai_message(self):
        """从API获取智能消息（带配置打印）"""
        try:
            current_time = time.time()
            if current_time - self.last_api_call_time < self.api_cooldown:
                # print(f"[INFO] 技能冷却中，剩余时间：{self.api_cooldown - int(current_time - self.last_api_call_time)}秒")
                return
            self.last_request_time = time.time()
            config_path = os.path.expanduser("~/pet_gpt_config.json")

            # 打印配置文件路径
            if not os.path.exists(config_path):
                # 明确提示文件不存在
                return
            with open(config_path) as f:
                config = json.load(f)

            # 打印加载的配置（隐藏敏感信息）
            safe_config = config.copy()
            safe_config["api_key"] = "***" + config["api_key"][-4:]  # 隐藏大部分API密钥

            headers = {
                "Authorization": f"Bearer {config['api_key']}",
                "Content-Type": "application/json"
            }

            prompt = "我的名字叫oo 也是杰哥的灵宠，你可以加一些 呀~ 丫！ 哦！ 这些语气词，然后你可以在生成的后面加两个表情，（生成的必须7字以内）"
            request_data = {
                "model": "gpt-3.5-turbo",
                "messages": [
                    {
                        "role": "system",
                        "content": prompt
                    }, {
                        "role": "user",
                        "content": "请生成一句可爱的话~ 四个字符后面加一个 \n 用于回车"
                    }]
            }

            response = requests.post(
                config['api_url'],
                headers=headers,
                json=request_data,
                timeout=10
            )

            self.last_api_call_time = current_time
            if response.status_code == 200:
                result = response.json()
                reply = result['choices'][0]['message']['content']
                # print(f"[SUCCESS] 获取到回复: {reply}")
                self.master.after(0, self.show_random_bubble, reply, True)
            else:
                print(f"[ERROR] API请求失败: {response.text}")

        except json.JSONDecodeError as e:
            print(f"[ERROR] 配置文件格式错误: {str(e)}")
        except KeyError as e:
            print(f"[ERROR] 配置文件缺少关键字段: {str(e)}")
        except Exception as e:
            print(f"[ERROR] 获取消息失败: {str(e)}")

    def start_drag(self, event):
        """开始拖拽"""
        self._drag_start_x = event.x
        self._drag_start_y = event.y

    def on_drag(self, event):
        """处理拖拽移动"""
        x = self.master.winfo_x() + (event.x - self._drag_start_x)
        y = self.master.winfo_y() + (event.y - self._drag_start_y)
        self.show_random_bubble("💫💫💫晕~")
        self.master.geometry(f"+{x}+{y}")

        if hasattr(self, 'current_bubble') and self.current_bubble.winfo_exists():
            bubble_x = x - 25
            bubble_y = y - 80
            self.current_bubble.geometry(f"+{bubble_x}+{bubble_y}")



    def on_click_pet(self, event):
        """处理单击宠物事件"""
        # 优先处理睡眠状态点击
        if self.is_sleeping:
            self.sleep_clicks += 1
            if self.sleep_clicks == 1:
                self.show_random_bubble("💤 别吵我睡觉...")
            elif self.sleep_clicks >= 2:
                self.wake_up(manual=True)
            return  # 直接返回，不执行后续逻辑

        # 以下是智能回复和普通点击逻辑
        if self.smart_reply_enabled:
            current_time = time.time()
            if current_time - self.last_request_time < self.request_cooldown:
                self.show_random_bubble("🕒 思考需要时间哦...")
                return

            self.last_click_pos = (event.x, event.y)
            self.show_random_bubble("正在思考...")
            threading.Thread(target=self.handle_smart_click).start()
            return

        # 普通点击处理
        self.last_activity_time = time.time()
        if (abs(event.x - self._drag_start_x) < 5 and
                abs(event.y - self._drag_start_y) < 5):
            self.show_click_effect(event.x_root, event.y_root)
            msg = random.choice(self.click_messages)
            self.show_random_bubble(msg)
            self.pet_jump_animation()
            self.status["mood"] = min(100, self.status["mood"] + 3)
            self.notify_status_update()

    def handle_smart_click(self):
        """处理智能点击"""
        try:
            config_path = os.path.expanduser("~/pet_gpt_config.json")
            with open(config_path) as f:
                config = json.load(f)

            prompt = f"用户点击了位置({self.last_click_pos[0]},{self.last_click_pos[1]}), 请生成有趣的回应，字数控制在5个字符"

            headers = {
                "Authorization": f"Bearer {config['api_key']}",
                "Content-Type": "application/json"
            }

            request_data = {
                "model": "gpt-3.5-turbo",
                "messages": [{
                    "role": "user",
                    "content": prompt
                }]
            }

            response = requests.post(
                config['api_url'],
                headers=headers,
                json=request_data,
                timeout=15
            )

            if response.status_code == 200:
                result = response.json()
                reply = result['choices'][0]['message']['content']
                self.master.after(0, self._update_click_message, reply)
        except Exception as e:
            self.master.after(0, self.show_random_bubble, f"思考失败：{str(e)}")

    def _update_click_message(self, new_message):
        """更新点击消息"""
        if len(self.click_messages) > 10:
            self.click_messages.pop(0)
        self.click_messages.append(new_message)
        self.show_random_bubble(new_message)

    def show_click_effect(self, x, y):
        """显示点击特效"""
        effect = tk.Toplevel(self.master)
        effect.overrideredirect(True)
        effect.wm_attributes("-topmost", True)
        effect.wm_attributes("-transparentcolor", "white")

        canvas = tk.Canvas(effect, bg="white", highlightthickness=0)
        canvas.pack()

        # 绘制爱心特效
        for i in range(1):
            canvas.create_text(20, 20 + i * 20,
                               text="❤",
                               font=("Arial", 12),
                               fill="#FF69B4")

        effect.geometry(f"+{x - 20}+{y - 30}")
        effect.after(500, effect.destroy)

    def pet_jump_animation(self):
        """跳跃动画效果"""
        original_y = self.master.winfo_y()

        # 跳跃轨迹
        jump_steps = [
            (0, -30), (0, -50), (0, -30),
            (0, 0), (0, -20), (0, 0)
        ]

        for dx, dy in jump_steps:
            new_x = self.master.winfo_x() + dx
            new_y = original_y + dy
            self.master.geometry(f"+{new_x}+{new_y}")
            self.master.update()
            time.sleep(0.05)

        # 恢复原位
        self.master.geometry(f"+{self.master.winfo_x()}+{original_y}")

    def mouse_follow(self):
        """鼠标跟随功能"""
        if hasattr(self, 'following_mouse') and self.following_mouse:
            return

        # 进入跟随模式
        self.following_mouse = True
        self.show_random_bubble("🐭 进入鼠标跟随模式\n(按ESC退出)")

        # 绑定ESC键事件
        self.master.bind('<Escape>', self.stop_following)

        # 开始跟随循环
        def follow_cursor():
            if self.following_mouse:
                try:
                    # 获取鼠标位置（相对屏幕）
                    x = self.master.winfo_pointerx()
                    y = self.master.winfo_pointery()

                    # 计算宠物位置（让宠物中心跟随鼠标）
                    pet_size = 70  # 宠物尺寸
                    self.master.geometry(f"+{x - pet_size // 2}+{y - pet_size // 2}")

                    # 每50ms更新一次位置
                    self.master.after(50, follow_cursor)
                except Exception as e:
                    print(f"跟随错误: {str(e)}")
                    self.stop_following()

        follow_cursor()

    def stop_following(self, event=None):
        """停止跟随"""
        if hasattr(self, 'following_mouse') and self.following_mouse:
            self.following_mouse = False
            self.master.unbind('<Escape>')
            self.show_random_bubble("🚫 退出跟随模式")

            # 重置窗口属性
            self.master.wm_attributes("-topmost", True)

            # 恢复事件绑定
            self.label.bind("<B1-Motion>", self.on_drag)

    def check_activity(self):
        """检查用户不活动状态"""
        # 修改后的判断逻辑
        if not any([self.is_sleeping, self.is_crying, self.is_hiding]):
            inactive_mins = (time.time() - self.last_activity_time) // 60

            # 优先处理睡眠状态
            if inactive_mins >= 3 and not self.is_sleeping:
                self.enter_sleep_mode()
            # 在非睡眠状态下检查捉迷藏
            elif inactive_mins >= 5 and not self.is_hiding:
                self.start_hide()

        self.master.after(30000, self.check_activity)



    def enter_sleep_mode(self):
        """进入睡眠状态"""
        if any([self.is_sleeping, self.is_hiding]):
            return
        if self.is_sleeping:
            return

        self.is_sleeping = True
        self.sleep_clicks = 0
        self.current_frames = self.sleep_frames
        self.current_frame = 0
        self.show_random_bubble("Zzz...好困...")
        self.last_activity_time = time.time()

        # 10分钟后自动唤醒
        self.master.after(600000, self.wake_up)

    def wake_up(self, manual=False):
        """唤醒宠物"""
        if not self.is_sleeping:
            return

        self.is_sleeping = False
        self.current_frames = self.pet_frames
        self.current_frame = 0
        self.last_activity_time = time.time()

        if manual:
            self.show_random_bubble("😴 啊～被吵醒了！")
        else:
            self.show_random_bubble("🌞 自然醒真舒服～")

        # 播放伸懒腰动画
        self.pet_stretch_animation()

    def pet_stretch_animation(self):
        """伸懒腰动画"""
        original_x = self.master.winfo_x()
        original_y = self.master.winfo_y()

        # 拉伸动画步骤
        stretch_steps = [
            (0, -5), (-5, 0), (5, 0),
            (0, 5), (0, 0)
        ]

        for dx, dy in stretch_steps:
            new_x = original_x + dx
            new_y = original_y + dy
            self.master.geometry(f"+{new_x}+{new_y}")
            self.master.update()
            time.sleep(0.1)

        # 恢复原位
        self.master.geometry(f"+{original_x}+{original_y}")

    def mouse_movement_handler(self, event):
        """检测鼠标晃动"""
        if self.is_hiding:
            self.mouse_movement += 1
            if self.mouse_movement > 30:  # 移动阈值
                self.end_hide()

    def start_hide(self):
        """开始捉迷藏"""
        if any([self.is_sleeping, self.is_crying, self.is_hiding]):
            return

        self.is_hiding = True
        self.mouse_movement = 0
        self.hide_start_time = time.time()
        self.last_activity_time = time.time()

        # 随机选择躲藏位置类型
        hide_type = random.choice(['folder', 'window', 'corner'])

        # 获取屏幕尺寸
        screen_width = self.master.winfo_screenwidth()
        screen_height = self.master.winfo_screenheight()

        # 根据类型计算位置
        if hide_type == 'folder':
            # 模拟在系统常见文件夹位置（右下角区域）
            x = screen_width - 200
            y = screen_height - 150
            self.hide_spot = (x, y, "desktop_folder")
        elif hide_type == 'window':
            # 随机选择窗口边缘位置
            x = random.randint(100, screen_width-200)
            y = random.randint(100, screen_height-200)
            self.hide_spot = (x, y, "window_edge")
        else:
            # 屏幕四角
            corners = [
                (50, 50),
                (screen_width-150, 50),
                (50, screen_height-150),
                (screen_width-150, screen_height-150)
            ]
            x, y = random.choice(corners)
            self.hide_spot = (x, y, "screen_corner")

        # 移动宠物并调整透明度
        self.master.geometry(f"+{x}+{y}")
        self.master.wm_attributes("-alpha", 1)

        # 显示提示气泡
        self.show_random_bubble("🐾 我要藏起来啦！\n晃动鼠标找我～", force=True)

        # 启动检查定时器
        self.hide_check_timer = self.master.after(1000, self.check_hide_status)
        self.current_frames = self.hide_frames
        self.current_frame = 0

    def end_hide(self):
        """结束躲藏"""
        if not self.is_hiding:
            return

        self.is_hiding = False
        self.master.wm_attributes("-alpha", 1.0)

        # 计算躲藏时间
        hide_duration = time.time() - self.hide_start_time
        time_score = min(30, int(hide_duration))  # 最大30分

        # 显示找到提示
        self.show_random_bubble(
            f"🎉 被你找到啦！\n"
            f"躲藏时间：{int(hide_duration)}秒\n"
            f"获得{time_score}心情值！"
        )

        # 增加心情值
        self.status["mood"] = min(100, self.status["mood"] + time_score)
        self.notify_status_update()

        # 取消定时器
        if self.hide_check_timer:
            self.master.after_cancel(self.hide_check_timer)
            self.current_frames = self.pet_frames
            self.current_frame = 0
            self.master.wm_attributes("-alpha", 1.0)  # 恢复不透明

    def check_hide_status(self):
        """检查躲藏状态"""
        if self.is_hiding:
            # 每1秒检测一次
            self.hide_check_timer = self.master.after(1000, self.check_hide_status)

            # 如果超过2分钟自动结束
            if time.time() - self.hide_start_time > 120:
                self.end_hide()
                self.show_random_bubble("😴 等太久...自己出来了", force=True)

    def close_window(self, event=None):
        """关闭窗口"""
        self.save_status()
        self.master.after_cancel(self.status_timer)
        self.master.after_cancel(self.bubble_timer)
        keyboard.unhook_all()  # 清除所有键盘监听
        self.master.destroy()


# 新增定时功能窗口类

class TimingWindow(tk.Toplevel):
    def __init__(self, master):
        super().__init__(master)
        self.title("功能设置中心")
        self.geometry("600x400")
        self.resizable(False, False)

        # 初始化样式
        self.setup_style()

        # 创建主容器
        self.main_frame = ttk.Frame(self)
        self.main_frame.pack(fill='both', expand=True)

        # 创建左侧菜单栏
        self.create_sidebar()

        # 创建右侧内容区
        self.content_area = ttk.Frame(self.main_frame, style='Content.TFrame')
        self.content_area.pack(side='right', fill='both', expand=True, padx=5, pady=5)

        # 存储当前显示的内容页
        self.current_page = None
        self.pages = {}

        # 初始化默认页面
        self.show_page('reminder')

        # 存储定时任务
        self.scheduled_task = None
        self.running = False

    def on_status_update(self, new_status):
        """接收来自主窗口的状态更新"""
        if self.current_page == 'monitor':
            self.update_monitor_data(force=True)

    def setup_style(self):
        """配置界面样式"""
        style = ttk.Style()
        style.configure('Sidebar.TFrame', background='#f0f0f0')
        style.configure('Sidebar.TButton',
                        width=15,
                        padding=10,
                        font=('微软雅黑', 10),
                        anchor='w',
                        background='#f0f0f0',
                        relief='flat')
        style.map('Sidebar.TButton',
                  background=[('active', '#e0e0e0')],
                  foreground=[('active', 'black')])
        style.configure('Content.TFrame', padding=20)

    def create_sidebar(self):
        """创建左侧菜单栏"""
        sidebar = ttk.Frame(self.main_frame, style='Sidebar.TFrame', width=150)
        sidebar.pack(side='left', fill='y')

        menu_items = [
            ('⏰ 定时提醒', 'reminder'),
            ('⚙️ 高级设置', 'settings'),
            ('📊 状态监控', 'monitor'),
            ('🤖 大模型设置', 'gpt_settings'),
            ('🎨 皮肤设置', 'appearance'),
            ('🐟 关于', 'about')
        ]

        for text, page_key in menu_items:
            btn = ttk.Button(sidebar,
                             text=text,
                             style='Sidebar.TButton',
                             command=lambda k=page_key: self.show_page(k))
            btn.pack(fill='x', pady=2)

    def show_page(self, page_key):
        """切换显示内容页"""
        if self.current_page:
            self.pages[self.current_page].pack_forget()

        if page_key not in self.pages:
            self.create_page(page_key)

        self.pages[page_key].pack(fill='both', expand=True)
        self.current_page = page_key

    def create_page(self, page_key):
        """创建不同内容页"""
        container = ttk.Frame(self.content_area)

        if page_key == 'reminder':
            self.create_reminder_page(container)
        elif page_key == 'settings':
            self.create_settings_page(container)
        elif page_key == 'monitor':
            self.create_monitor_page(container)
        elif page_key == 'gpt_settings':
            self.create_gpt_settings_page(container)
        elif page_key == 'appearance':
            self.create_appearance_page(container)
        elif page_key == 'about':
            self.create_about_page(container)

        self.pages[page_key] = container

    def create_reminder_page(self, parent):
        """创建定时提醒页面"""
        # 时间间隔设置
        ttk.Label(parent, text="提醒间隔（分钟）:").grid(row=0, column=0, sticky='w', pady=5)
        self.interval = ttk.Spinbox(parent, from_=1, to=240, width=8)
        self.interval.grid(row=0, column=1, sticky='ew', padx=5, pady=5)
        self.interval.set(30)

        # 提醒内容设置
        ttk.Label(parent, text="提醒内容:").grid(row=1, column=0, sticky='w', pady=5)
        self.message = ttk.Entry(parent, width=40)
        self.message.grid(row=1, column=1, sticky='ew', padx=5, pady=5)
        self.message.insert(0, "该休息一下啦！")

        # 控制按钮
        btn_frame = ttk.Frame(parent)
        btn_frame.grid(row=2, column=0, columnspan=2, pady=15)

        self.start_btn = ttk.Button(btn_frame, text="开始提醒", command=self.toggle_reminder)
        self.start_btn.pack(side='left', padx=5)

    def create_settings_page(self, parent):
        """创建系统设置页面"""
        ttk.Label(parent, text="系统设置", font=('微软雅黑', 12, 'bold')).pack(anchor='w')

        # 开机自启动
        self.auto_start_var = tk.BooleanVar()
        ttk.Checkbutton(parent,
                        text="开机自动启动",
                        variable=self.auto_start_var,
                        command=self.toggle_auto_start).pack(anchor='w', pady=5)

        # 透明度设置
        ttk.Label(parent, text="窗口透明度:").pack(anchor='w', pady=5)
        self.opacity_scale = ttk.Scale(parent,
                                       from_=0.3,
                                       to=1.0,
                                       value=1.0,
                                       command=lambda v: self.master.wm_attributes('-alpha', float(v)))
        self.opacity_scale.pack(fill='x')

    def create_monitor_page(self, parent):
        """创建状态监控页面-动态版本"""
        self.last_update_time = 0  # 记录最后更新时间
        columns = ('name', 'value')
        self.status_tree = ttk.Treeview(parent, columns=columns, show='headings', height=5)

        # 设置列
        self.status_tree.heading('name', text='状态项')
        self.status_tree.heading('value', text='当前值')
        self.status_tree.column('name', width=120)
        self.status_tree.column('value', width=80)
        self.status_tree.pack(fill='both', expand=True)

        # 初始化数据
        self.update_monitor_data()

        # 启动定时更新
        self.monitor_update_timer = self.after(1000, self.update_monitor_data)

    def update_monitor_data(self, force=False):
        """更新监控数据"""
        try:
            main_app = self.master._transparent_window
            status = main_app.status

            # 添加强制更新判断
            if not force and status['last_saved'] == self.last_update_time:
                return

            self.last_update_time = time.time()

            # 计算运行时间
            run_seconds = int(time.time() - status.get('last_saved', time.time()))
            run_time = f"{run_seconds // 3600}h {(run_seconds % 3600) // 60}m"

            # 构建状态项
            status_items = [
                ('心情值', f"{status.get('mood', 0)}%"),
                ('饱腹度', f"{status.get('hunger', 0)}%"),
                ('口渴度', f"{status.get('thirst', 0)}%"),
                ('运行时间', run_time)
            ]

            # 清空旧数据
            for item in self.status_tree.get_children():
                self.status_tree.delete(item)

            # 插入新数据
            for item in status_items:
                self.status_tree.insert('', 'end', values=item)

        except Exception as e:
            print()

        # 保持定时更新
        self.monitor_update_timer = self.after(5000, self.update_monitor_data)

    def create_appearance_page(self, parent):
        """创建外观设置页面"""
        ttk.Label(parent, text="选择宠物皮肤:").pack(anchor='w')

        skin_frame = ttk.Frame(parent)
        skin_frame.pack(fill='x', pady=10)

        skins = ['默认皮肤', '科技蓝', '可爱粉', '暗黑系']
        for skin in skins:
            btn = ttk.Button(skin_frame,
                             text=skin,
                             command=lambda s=skin: self.change_skin(s))
            btn.pack(side='left', padx=5)

    def toggle_auto_start(self):
        """切换开机自启动"""
        if self.auto_start_var.get():
            auto_start()
            BubbleWindow(self.master, "✅ 已启用开机自启动")
        else:
            # 需要实现禁用自启动的逻辑
            BubbleWindow(self.master, "❌ 已禁用开机自启动")

    def toggle_reminder(self):
        """切换提醒状态"""
        if not self.running:
            try:
                minutes = int(self.interval.get())
                if minutes < 1 or minutes > 240:
                    raise ValueError
                self.start_reminder(minutes * 60000)
                self.start_btn.config(text="停止提醒")
                self.running = True
                # 添加操作反馈
                main_window = self.master._transparent_window.master
                BubbleWindow(main_window, f"⏰ 已开启{minutes}分钟定时提醒")
            except ValueError:
                BubbleWindow(self.master, "请输入1-240之间的整数")
        else:
            self.stop_reminder()
            self.start_btn.config(text="开始提醒")
            self.running = False
            # 添加停止反馈
            main_window = self.master._transparent_window.master
            BubbleWindow(main_window, "⏰ 定时提醒已关闭")

    def start_reminder(self, interval):
        """启动定时提醒"""
        self.scheduled_task = self.master.after(interval, self.show_reminder)

    def show_reminder(self):
        """显示提醒"""
        msg = self.message.get() or "该休息一下啦！"

        main_window = self.master._transparent_window.master
        BubbleWindow(main_window, msg)

        # 重新启动定时器（循环提醒）
        if self.running:
            self.start_reminder(int(self.interval.get()) * 60000)

    def stop_reminder(self):
        """停止提醒"""
        if self.scheduled_task:
            self.master.after_cancel(self.scheduled_task)
            self.scheduled_task = None

    def create_about_page(self, parent):
        """创建关于页面"""
        container = ttk.Frame(parent, padding=20)
        container.pack(fill='both', expand=True)  # 关键布局代码

        # 样式配置
        title_style = ('微软雅黑', 16, 'bold')
        header_style = ('微软雅黑', 11)
        text_style = ('微软雅黑', 10)
        link_style = ('微软雅黑', 10, 'underline')

        # 主标题
        ttk.Label(container,
                  text="桌面萌宠小助手",
                  font=title_style,
                  foreground="#2c3e50").pack(pady=(0, 20))

        # 信息表格布局
        info_frame = ttk.Frame(container)
        info_frame.pack(fill='x', pady=5)
        # 版本信息
        ttk.Label(info_frame, text="版本：", width=8, anchor='e').grid(row=0, column=0, sticky='ew', padx=2)
        ttk.Label(info_frame, text="v2.2.0", foreground="#3498db").grid(row=0, column=1, sticky='w')

        # 开发者信息
        ttk.Label(info_frame, text="开发者：", width=8, anchor='e').grid(row=1, column=0, sticky='ew', padx=2, pady=5)
        ttk.Label(info_frame, text="杰哥力挽狂澜", foreground="#e74c3c").grid(row=1, column=1, sticky='w')

        # 编译日期
        ttk.Label(info_frame, text="编译日期：", width=8, anchor='e').grid(row=2, column=0, sticky='ew', padx=2)
        ttk.Label(info_frame, text="202-03-15").grid(row=2, column=1, sticky='w')

        # 版权信息
        ttk.Label(container,
                  text="© 2025 版权所有，保留所有权利",
                  font=text_style,
                  foreground="#27ae60").pack(pady=10)

        # 链接区域
        link_frame = ttk.Frame(container)
        link_frame.pack(pady=15)

        # GitHub链接
        github_link = ttk.Label(link_frame,
                                text="Gitee仓库",
                                foreground="#2980b9",
                                cursor="hand2",
                                font=link_style)
        github_link.pack(side='left', padx=10)
        github_link.bind("<Button-1>", lambda e: webbrowser.open("https://gitee.com/itotonte/desktop_pet"))

        # 文档链接
        docs_link = ttk.Label(link_frame,
                              text="使用文档",
                              foreground="#8e44ad",
                              cursor="hand2",
                              font=link_style)
        docs_link.pack(side='left', padx=10)
        docs_link.bind("<Button-1>", lambda e: webbrowser.open("https://gitee.com/itotonte/desktop_pet"))

        # 技术支持
        ttk.Label(container,
                  text="技术支持：veteranJaybrother",
                  font=text_style,
                  foreground="#7f8c8d").pack(pady=5)

        # 开源协议
        license_frame = ttk.Frame(container)
        license_frame.pack(fill='x', pady=10)
        ttk.Label(license_frame,
                  text="基于MIT开源协议发布",
                  font=('微软雅黑', 9),
                  foreground="#95a5a6").pack(side='left')

        # 开源协议链接
        license_link = ttk.Label(license_frame,
                                 text="查看协议内容",
                                 font=('微软雅黑', 9, 'underline'),
                                 foreground="#95a5a6",
                                 cursor="hand2")
        license_link.pack(side='left', padx=5)
        license_link.bind("<Button-1>", lambda e: webbrowser.open("https://opensource.org/licenses/MIT"))
        return container

    def create_gpt_settings_page(self, parent):
        """创建大模型设置页面（修正版）"""
        # 使用传入的parent容器而不是新建container
        parent.grid_rowconfigure(2, weight=1)
        parent.grid_columnconfigure(1, weight=1)

        # 配置文件路径
        self.gpt_config_file = os.path.expanduser("~/pet_gpt_config.json")
        self.gpt_config = self.load_gpt_config()

        # URL设置
        ttk.Label(parent, text="API URL:").grid(row=0, column=0, sticky='w', pady=5)
        self.api_url = ttk.Entry(parent, width=40)
        self.api_url.grid(row=0, column=1, sticky='ew', padx=5, pady=5)
        self.api_url.insert(0, self.gpt_config.get('api_url', ''))

        # API Key设置
        ttk.Label(parent, text="API Key:").grid(row=1, column=0, sticky='w', pady=5)
        self.api_key = ttk.Entry(parent, width=40, show='*')
        self.api_key.grid(row=1, column=1, sticky='ew', padx=5, pady=5)
        self.api_key.insert(0, self.gpt_config.get('api_key', ''))

        # 训练文本编辑
        ttk.Label(parent, text="训练配置(JSON):").grid(row=2, column=0, sticky='nw', pady=5)
        self.training_text = tk.Text(parent, width=50, height=15, wrap='word')
        self.training_text.grid(row=2, column=1, sticky='nsew', padx=5, pady=5)

        # 插入默认配置
        default_config = {
            "model": "gpt-3.5-turbo",
            "messages": [
                {
                    "role": "system",
                    "content": "你是一个文案专家..."
                }
            ]
        }
        current_config = self.gpt_config.get('training', default_config)
        self.training_text.insert('1.0', json.dumps(current_config, indent=2))

        # 保存按钮
        save_btn = ttk.Button(parent, text="保存配置", command=self.save_gpt_config)
        save_btn.grid(row=3, column=1, sticky='e', pady=10)
    def load_gpt_config(self):
        """加载大模型配置"""
        default_config = {
            "api_url": "",
            "api_key": "",
            "training": {
                "model": "gpt-3.5-turbo",
                "messages": [
                    {
                        "role": "system",
                        "content": "你是一个文案专家...（原内容）"
                    }
                ]
            }
        }

        try:
            if os.path.exists(self.gpt_config_file):
                with open(self.gpt_config_file, 'r') as f:
                    return json.load(f)
            return default_config
        except:
            return default_config

    def save_gpt_config(self):
        """保存大模型配置"""
        try:
            config = {
                "api_url": self.api_url.get(),
                "api_key": self.api_key.get(),
                "training": json.loads(self.training_text.get('1.0', 'end'))
            }

            # 验证JSON格式
            json.dumps(config)  # 测试是否可以序列化

            with open(self.gpt_config_file, 'w') as f:
                json.dump(config, f, indent=2)

            BubbleWindow(self.master, "✅ 配置保存成功！")
        except json.JSONDecodeError:
            BubbleWindow(self.master, "❌ JSON格式错误，请检查配置！")
        except Exception as e:
            BubbleWindow(self.master, f"保存失败：{str(e)}")

    def destroy(self):
        """关闭窗口时停止所有定时器"""
        if hasattr(self, 'monitor_update_timer'):
            self.after_cancel(self.monitor_update_timer)
        self.stop_reminder()
        super().destroy()


# 开始运行
if __name__ == "__main__":
    root = TkinterDnD.Tk()
    root.geometry("70x70")
    window = TransparentGifWindow(root, "")
    root.mainloop()
